﻿using System;
using System.Collections.Generic;
using TestBat.IModels.Domain;

namespace TestBat.IModels.Models
{
    public interface IScheduleModel : IModel
    {
        ISchedule GetByID(Guid ID);

        /// <summary>
        /// save/persist a schedule
        /// </summary>
        /// <param name="schedule">the schedule to persist</param>
        void Save(ISchedule schedule);

        /// <summary>
        /// remove the schedule from the DB
        /// </summary>
        /// <param name="schedule">the schedule to remove</param>
        void Delete(ISchedule schedule);

        /// <summary>
        /// revert a schedule back to database-state
        /// </summary>
        /// <param name="schedule">the schedule</param>
        void Revert(ISchedule schedule);

        /// <summary>
        /// create a new schedule
        /// </summary>
        /// <returns>a new persistent schedule</returns>
        ISchedule Create();

        /// <summary>
        /// retrieves all schedule tasks of a schedule
        /// </summary>
        /// <param name="schedule">the schedule to get the tasks from</param>
        /// <returns>a list of schedule tasks</returns>
        IList<IScheduleTask> GetScheduleTasks(ISchedule schedule);

        IList<IScheduleTraineeGroup> GetScheduleTraineeGroups(ISchedule schedule);

        /// <summary>
        /// add a schedule task to a schedule
        /// </summary>
        /// <param name="schedule">the schedule to add the task to</param>
        /// <param name="task">the task contained in the item</param>
        /// <param name="after">the item after which to add the new one (null, if at first position)</param>
        /// <returns>the newly created schedule item</returns>
        IScheduleTask AddScheduleTask(ISchedule schedule, ITask task, IScheduleTask after);

        /// <summary>
        /// add schedule items to a schedule
        /// </summary>
        /// <param name="schedule">the schedule to add the items to</param>
        /// <param name="tasks">the tasks, which should be contained in the items</param>
        /// <param name="after">the item after which to add the new ones (null, if at first position)</param>
        /// <returns>the newly created schedule item list</returns>
        IList<IScheduleTask> AddScheduleTasks(ISchedule schedule, IList<ITask> tasks, IScheduleTask after);

        /// <summary>
        /// remove a schedule item from a schedule
        /// </summary>
        /// <param name="schedule">the schedule to remove the item from</param>
        /// <param name="item">the item to remove</param>
        void RemoveScheduleTask(ISchedule schedule, IScheduleTask item);

        /// <summary>
        /// move up a schedule item
        /// </summary>
        /// <param name="schedule">the schedule</param>
        /// <param name="item">the item to move up</param>
        void MoveScheduleTaskUp(ISchedule schedule, IScheduleTask item);

        /// <summary>
        /// move down a schedule item
        /// </summary>
        /// <param name="schedule">the schedule</param>
        /// <param name="item">the item to move down</param>
        void MoveScheduleTaskDown(ISchedule schedule, IScheduleTask item);

        IScheduleTraineeGroup AddScheduleTraineeGroup(ISchedule schedule, ITraineeGroup traineeGroup);
        void RemoveScheduleTraineeGroup(ISchedule schedule, IScheduleTraineeGroup traineeGroup);

        /// <summary>
        /// get all schedules
        /// </summary>
        /// <returns>all schedules</returns>
        IList<ISchedule> GetAll();

        /// <summary>
        /// get all running schedules
        /// </summary>
        /// <returns>all running schedules</returns>
        IList<ISchedule> GetRunning();

        IList<ISchedule> GetRunningForTrainee(ITrainee trainee);

        IList<ITrainee> GetTrainees(ISchedule schedule); // TODO: doesn't belong here

        //IList<ITrainee> GetTraineesTestGraded(ISchedule schedule); // TODO: doesn't belong here
        //IList<ITrainee> GetTraineesTestNotGraded(ISchedule schedule); // TODO: doesn't belong here

        IList<ITest> GetGradedTests(ISchedule schedule);
    }
}
